package com.bookworld.service;

import com.bookworld.dao.BookDao;
import com.bookworld.model.Book;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cache.annotation.CacheEvict;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.time.LocalDateTime;
import java.util.List;

@Service
@Transactional
public class BookService {
    
    @Autowired
    private BookDao bookDao;
    
    @Cacheable(value = "books", key = "#id")
    public Book findById(Long id) {
        return bookDao.findById(id);
    }
    
    @Cacheable(value = "books", key = "#isbn")
    public Book findByIsbn(String isbn) {
        return bookDao.findByIsbn(isbn);
    }
    
    @Cacheable(value = "books", key = "'active-page-' + #page + '-' + #size")
    public List<Book> findAllActiveWithPagination(int page, int size) {
        int offset = (page - 1) * size;
        return bookDao.findAllActiveWithPagination(size, offset);
    }
    
    @Cacheable(value = "books", key = "'featured-' + #limit")
    public List<Book> findFeaturedBooks(int limit) {
        return bookDao.findFeaturedBooks(limit);
    }
    
    @Cacheable(value = "books", key = "'category-' + #categoryId + '-' + #page + '-' + #size")
    public List<Book> findByCategory(Long categoryId, int page, int size) {
        int offset = (page - 1) * size;
        return bookDao.findByCategory(categoryId, size, offset);
    }
    
    @Cacheable(value = "books", key = "'author-' + #authorId + '-' + #page + '-' + #size")
    public List<Book> findByAuthor(Long authorId, int page, int size) {
        int offset = (page - 1) * size;
        return bookDao.findByAuthor(authorId, size, offset);
    }
    
    @Cacheable(value = "books", key = "'bestsellers-' + #limit")
    public List<Book> findBestSellers(int limit) {
        return bookDao.findBestSellers(limit);
    }
    
    @Cacheable(value = "books", key = "'search-' + #keyword + '-' + #page + '-' + #size")
    public List<Book> search(String keyword, int page, int size) {
        int offset = (page - 1) * size;
        return bookDao.search(keyword, size, offset);
    }
    
    @CacheEvict(value = "books", allEntries = true)
    public Book save(Book book) {
        if (book.getId() == null) {
            // 新建图书
            book.setActive(true);
            book.setFeatured(false);
            book.setViewCount(0);
            book.setSoldCount(0);
            book.setRating(BigDecimal.ZERO);
            book.setCreatedAt(LocalDateTime.now());
            book.setUpdatedAt(LocalDateTime.now());
            bookDao.insert(book);
        } else {
            // 更新图书
            Book existingBook = bookDao.findById(book.getId());
            if (existingBook == null) {
                throw new RuntimeException("图书不存在");
            }
            book.setUpdatedAt(LocalDateTime.now());
            bookDao.update(book);
        }
        return book;
    }
    
    @CacheEvict(value = "books", allEntries = true)
    public void updateActiveStatus(Long id, Boolean active) {
        bookDao.updateActiveStatus(id, active);
    }
    
    @CacheEvict(value = "books", allEntries = true)
    public boolean decreaseStock(Long id, int quantity) {
        int affectedRows = bookDao.decreaseStock(id, quantity);
        return affectedRows > 0;
    }
    
    @CacheEvict(value = "books", allEntries = true)
    public void increaseStock(Long id, int quantity) {
        bookDao.increaseStock(id, quantity);
    }
    
    @CacheEvict(value = "books", key = "#id")
    public void incrementViewCount(Long id) {
        bookDao.incrementViewCount(id);
    }
    
    @CacheEvict(value = "books", key = "#id")
    public void incrementSoldCount(Long id, int quantity) {
        bookDao.incrementSoldCount(id, quantity);
    }
    
    @CacheEvict(value = "books", allEntries = true)
    public void delete(Long id) {
        bookDao.delete(id);
    }
    
    public int countActive() {
        return bookDao.countActive();
    }
    
    public int countByCategory(Long categoryId) {
        return bookDao.countByCategory(categoryId);
    }
    
    public int countByAuthor(Long authorId) {
        return bookDao.countByAuthor(authorId);
    }
    
    public int countBySearch(String keyword) {
        return bookDao.countBySearch(keyword);
    }
    
    public boolean isStockAvailable(Long bookId, int quantity) {
        Book book = bookDao.findById(bookId);
        return book != null && book.getStock() >= quantity;
    }
    
    public BigDecimal calculateDiscountPrice(BigDecimal originalPrice, BigDecimal discountPercent) {
        if (discountPercent == null || discountPercent.compareTo(BigDecimal.ZERO) <= 0) {
            return originalPrice;
        }
        
        BigDecimal discountAmount = originalPrice.multiply(discountPercent).divide(BigDecimal.valueOf(100));
        return originalPrice.subtract(discountAmount);
    }
}
